package com.yj.processor;

import com.yj.anno.RpcReference;
import com.yj.proxy.RpcProxy;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ApplicationContextEvent;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

@Component
@Slf4j
public class RpcReferenceBeanPostProcessor implements BeanPostProcessor, ApplicationListener<ContextRefreshedEvent> {


    @Autowired
    private RpcProxy rpcProxy;

    List<Object> rpcReferenceObject = new ArrayList<>();
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

        Field[] fields = bean.getClass().getDeclaredFields();
        for (Field field : fields) {
            if (field.isAnnotationPresent(RpcReference.class)) {
                rpcReferenceObject.add(bean);
            }
        }
        return bean;
    }

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        for (Object object: rpcReferenceObject) {
            try {
                Field[] fields = object.getClass().getDeclaredFields();
                for (Field field : fields) {
                    if (field.isAnnotationPresent(RpcReference.class)) {
                        RpcReference rpcReference = field.getAnnotation(RpcReference.class);
                        field.setAccessible(true);
                        Object proxy = rpcProxy.createProxy(field.getType());

                        field.set(object, proxy);
                    }

                }
            }catch(Exception e){
                log.error("rpc reference error",e);
            }
        }
    }
}
